#include "sessionfriendarea.h"
#include <QScrollBar>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QTime>
#include <QApplication>
#include <QDateTime>
#include <QStyleOption>
#include <QPainter>
#include <QDate>

#include "model/datacenter.h"
#include "mainwidget.h"
#include "debug.h"
#include "model/data.h"

using namespace model;

SessionFriendArea::SessionFriendArea(QWidget *parent)
    : QScrollArea{parent}
{
    // 1. 设置必要的属性
    this->setWidgetResizable(true);// 设置了这个属性, 才能开启滚动效果
    this->setFrameShape(QFrame::NoFrame);  // 去除边框
    this->setViewportMargins(0, 0, 0, 0);

    // 2. 初始化滚动条样式
    setupScrollBars();
    this->viewport()->installEventFilter(this);

    // 3. 创建 widget
    container = new QWidget();
    container->setFixedWidth(230);
    this->setWidget(container);

    // 4. 给 widget 指定布局管理器 方便后续添加元素
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setContentsMargins(0, 0, 0 , 0);
    layout->setSpacing(0);
    layout->setAlignment(Qt::AlignTop);
    container->setLayout(layout);

    // // 5. 测试滚动效果
    // for(int i = 0; i < 50; ++i){
    //     QPushButton* btn = new QPushButton();
    //     btn->setText("按钮");
    //     layout->addWidget(btn);
    // }

    // 构造出临时数据, 用来作为节目依据
#if TEST_UI
    QIcon icon(":/resource/image/man.png");
    for(int i = 0; i < 30; ++i){
        this->addItem(SessionItemType, QString::number(i),icon, "张三" + QString::number(i), "最后一条消息" + QString::number(i), "13:25");
    }
    QDateTime* time = new QDateTime();

    this->addItem(SessionItemType, QString::number(30), icon, "张三" + QString::number(30), "最后一条消息22222222222229898989822223333", time->currentDateTime().toString());
    this->addItem(FriendItemType, QString::number(31), icon, "张三" + QString::number(31), "最后一条消息22222222222229898989822223333");
    this->addItem(ApplyItemType, QString::number(32), icon, "张三" + QString::number(32));
#endif
}

void SessionFriendArea::clear(){
    QLayout* layout = container->layout();
    // 遍历布局管理局的所有元素 -- 但是这里有个问题, 就是删除当前元素, 后续元素会前移
    // 解决: 每次删除 0 / 从后往前删
    for(int i = layout->count() - 1; i >= 0; --i){
        QLayoutItem* item = layout->takeAt(i);
        if(item->widget()){
            delete item->widget();  // 把这个移除内容的 widget 进行释放
        }
        delete item;
    }
}

void SessionFriendArea::addItem(ItemType itemType, const QString&id, const QIcon &avatar,
                                const QString &name, const QString &text, const QString& time)
{
    // SessionFriendItem* item = new SessionFriendItem(this, avatar, name, text, time);

    SessionFriendItem* item = nullptr;
    if(itemType == SessionItemType){
        item = new SessionItem(this, id, avatar, name, text, time);
    }else if(itemType == FriendItemType){
        item = new FriendItem(this, id, avatar, name, text);
    }else if(itemType == ApplyItemType){
        item = new ApplyItem(this, id, avatar, name);
    }else{
        LOG() << "错误的 ItemType！itemType = " << itemType;
        return;
    }

    container->layout()->addWidget(item);
}

void SessionFriendArea::clickItem(int index){
    if(index < 0 || index >= container->layout()->count()){
        LOG() << "点击元素的下标超出范围! index=" << index;
    }
    QLayoutItem* layoutItem = container->layout()->itemAt(index);
    if(layoutItem == nullptr || layoutItem->widget() == nullptr){
        LOG() << "指定元素不存在！index=" << index;
        return ;
    }
    SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(layoutItem->widget());
    item->select();
}


void SessionFriendArea::setupScrollBars()
{
    // 水平滚动条隐藏
    this->horizontalScrollBar()->setStyleSheet(R"(
        QScrollBar:horizontal {
            height: 0px;
        }
    )");

    vScrollBarStyle = R"(
        QScrollBar:vertical {
            width: 8px;
            background-color: transparent;
            margin: 0px;
        }
        QScrollBar::handle:vertical {
            background-color: rgba(150, 150, 150, 180);
            min-height: 20px;
            border-radius: 3px;
            margin: 0px 0px 0px 0px;  /* 确保贴右 */
        }
        QScrollBar::handle:vertical:hover {
            background-color: rgba(120, 120, 120, 200);
        }
        QScrollBar::handle:vertical:pressed {
            background-color: rgba(80, 80, 80, 255);
        }
        QScrollBar::add-line, QScrollBar::sub-line,
        QScrollBar::add-page, QScrollBar::sub-page {
            background: none;
            width: 0px;
            height: 0px;
        }
    )";

    this->verticalScrollBar()->setStyleSheet(vScrollBarStyle);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

}

void SessionFriendArea::showVerticalScrollBar(){
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    this->verticalScrollBar()->setStyleSheet(vScrollBarStyle);
}

void SessionFriendArea::hideVerticalScrollBar(){
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

bool SessionFriendArea::eventFilter(QObject *obj, QEvent *event){
    if (obj == this->viewport()) {
        if (event->type() == QEvent::Enter) {
            showVerticalScrollBar();
            return false;
        } else if (event->type() == QEvent::Leave) {
            hideVerticalScrollBar();
            return false;
        }
    }
    return QScrollArea::eventFilter(obj, event);
}


SessionFriendItem::SessionFriendItem(QWidget* owner, const QIcon& avatar,
                                     const QString& name, const QString& text,
                                     const QString& time)
    : QWidget(owner), owner(owner)
{
    this->setFixedHeight(60);
    this->setAutoFillBackground(true);
    this->setAttribute(Qt::WA_Hover);
    this->setFocusPolicy(Qt::ClickFocus);

    // 创建主布局
    layout = new QGridLayout();  // 赋值给成员变量
    layout->setContentsMargins(10, 5, 10, 5);
    layout->setSpacing(6);
    this->setLayout(layout);

    // === 1. 头像 ===
    avatarBtn = new QPushButton();
    avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(36, 36);
    avatarBtn->setIcon(avatar);
    avatarBtn->setIconSize(QSize(36, 36));
    avatarBtn->setStyleSheet("QPushButton { border: none; background-color: transparent; border-radius: 5px; }");

    // === 2. 名字 ===
    nameLabel = new QLabel();
    nameLabel->setStyleSheet("QLabel { font: 400 12px 'Microsoft YaHei'; color: #333; }");
    nameLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    QFontMetrics fm(nameLabel->font());
    nameLabel->setText(fm.elidedText(name, Qt::ElideRight, 150));
    nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // === 3. 时间 ===
    timeLabel = new QLabel(time);
    timeLabel->setStyleSheet("QLabel { font: 400 10px 'Microsoft YaHei'; color: #999; }");
    timeLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    timeLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    // === 4. 消息预览 ===
    messageLabel = new QLabel();
    messageLabel->setStyleSheet("QLabel { font: 400 11px 'Microsoft YaHei'; color: #666; }");
    messageLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    messageLabel->setFixedHeight(20);
    QFontMetrics fmMsg(messageLabel->font());
    messageLabel->setText(fmMsg.elidedText(text, Qt::ElideRight, 170));


    // === 布局 ===
    layout->addWidget(avatarBtn,     0, 0, 2, 1, Qt::AlignCenter);
    layout->addWidget(nameLabel,     0, 1, 1, 1);
    layout->addWidget(timeLabel,     0, 2, 1, 1, Qt::AlignRight);
    layout->addWidget(messageLabel,  1, 1, 1, 2);  // 第二行，跨两列
}


void SessionFriendItem::paintEvent(QPaintEvent *event){
    (void) event;
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void SessionFriendItem::mousePressEvent(QMouseEvent *event){
    (void) event;
    select();
}

void SessionFriendItem::enterEvent(QEnterEvent *event){
    (void) event;
    if(!this->selected){
        this->setStyleSheet("QWidget{background-color: rgb(234, 234, 234);}");
    }
}

void SessionFriendItem::leaveEvent(QEvent *event){
    (void) event;
    if(!this->selected){
        this->setStyleSheet("QWidget{background-color: rgb(247, 247, 247);}");
    }
}

void SessionFriendItem::select(){
    // 还原之前选中元素背景色, 设置当前 item 背景
    // 遍历所有兄弟元素
    const QObjectList childs = this->parentWidget()->children();
    for(QObject* child: childs){
        if(!child->isWidgetType()) continue;

        // 确定是 widget, 把 child 强转
        SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(child);
        if(item->selected){
            item->selected = false;
            item->setStyleSheet("QWidget {background-color: rgb(247, 247, 247);}");
        }
    }
    this->setStyleSheet("QWidget{background-color: rgb(222, 222, 222);}");
    this->selected = true;

    // TODO 进一步加载详情, 按照多态的方式调用对应子类的 active
    this->active();
}


/* -------------------- 会话 Item 的实现 -------------------- */
SessionItem::SessionItem(QWidget *owner, const QString &chatSessionId, const QIcon &avatar,
                        const QString &name, const QString &lastMessage, const QString &time)
    :SessionFriendItem(owner, avatar, name, lastMessage), chatSessionId(chatSessionId), text(lastMessage)
{
    // 1. 处理更新最后一个消息的信号
    DataCenter* dataCenter = DataCenter::getInstance();
    connect(dataCenter, &DataCenter::updateLastMessage, this, &SessionItem::updateLastMessage);

    // 2. 显示未读消息数目
    int unread = dataCenter->getUnread(chatSessionId);
    if (unread > 0) {
        // 存在未读消息
        this->messageLabel->setText(QString("[未读%1条] ").arg(unread) + text);
    }
}

void SessionItem::active(){
    // 点击之后, 要加载会话的历史消息列表
    LOG() << "点击 SessionItem 触发的逻辑! chatSessionId=" << chatSessionId;

    // 1， 加载会话历史消息
    MainWidget* mainWidget = MainWidget::getInstance();
    mainWidget->loadRecentMessage(chatSessionId);

    // 2. 清空未读消息数据, 并且更新显示
    DataCenter* dataCenter = DataCenter::getInstance();
    dataCenter->clearUnread(chatSessionId);

    // 3. 更新界面的显示. 把会话消息预览这里, 前面的 "[未读x条]" 内容给干掉
    this->messageLabel->setText(text);
}

void SessionItem::updateLastMessage(const QString &chatSessionId){
    DataCenter* dataCenter = DataCenter::getInstance();
    // 1. 判断 chatSessionId 是否匹配
    if(this->chatSessionId != chatSessionId){
        return;
    }

    // 2. 更新最后一条消息
    QList<Message>* messageList = dataCenter->getRecentMessageList(chatSessionId);
    if(messageList == nullptr || messageList->size() == 0){
        return;
    }
    const Message& lastMessage = messageList->back();   // 获取

    // 3. 明确显示的文本内容
    if (lastMessage.messageType == TEXT_TYPE) {
        text = lastMessage.content;
    } else if (lastMessage.messageType == IMAGE_TYPE) {
        text = "[图片]";
    } else if (lastMessage.messageType == FILE_TYPE) {
        text = "[文件]";
    } else if (lastMessage.messageType == SPEECH_TYPE) {
        text = "[语音]";
    } else {
        LOG() << "错误的消息类型!";
        return;
    }

    // 4. 显示内容到界面
    //    注意: 针对这里的逻辑, 后续还需要考虑到 "未读消息" 情况. 关于未读消息的处理, 后续编写 "接收消息" 的时候再处理.
    //    先判定当前消息的会话是不是正在选中的会话. 如果是不更新任何未读消息, 反之看未读消息是否 > 0, 并且做出前缀的拼装
    if(chatSessionId == dataCenter->getCurrentChatSessionId()){
        this->messageLabel->setText(text);
    }else{
        int unread = dataCenter->getUnread(chatSessionId);
        if (unread > 0) {
            // 存在未读消息
            this->messageLabel->setText(QString("[未读%1条] ").arg(unread) + text);
        }
    }

}


/* -------------------- 好友 Item 的实现 -------------------- */
FriendItem::FriendItem(QWidget *owner, const QString &friendId, const QIcon &avatar,
                       const QString &name, const QString &description)
    :SessionFriendItem(owner, avatar, name, description), userId(friendId)
{

}

void FriendItem::active(){
    LOG() << "FriendItem active. userId=" << userId;
    // TODO

    MainWidget* mainWidget = MainWidget::getInstance();
    mainWidget->switchSession(userId);
}



/* -------------------- 好友申请 Item 的实现 -------------------- */
ApplyItem::ApplyItem(QWidget *owner, const QString &userId, const QIcon &avatar,
                     const QString &name)
    :SessionFriendItem(owner, avatar, name), userId(userId)
{
    // 1. 移除父类的 messageLabel
    if (messageLabel && layout) {
        layout->removeWidget(messageLabel);
        delete messageLabel;
        messageLabel = nullptr; // 释放内存 -- 避免内存泄露
    }

    // 2. 创建两个按钮
    QPushButton* acceptBtn = new QPushButton();
    acceptBtn->setText("同意");
    acceptBtn->setStyleSheet(R"(
        QPushButton {
           background-color: #4CAF50;
           border: none;
           border-radius: 8px;
           color: white;
           font-size: 12px;
           padding: 8px 15px;
        }
        QPushButton:hover {
            background-color: #45A049;
        }
        QPushButton:pressed {
            background-color: #39843C;
        }
    )");
    acceptBtn->setFixedWidth(80);
    QPushButton* rejectBtn = new QPushButton();
    rejectBtn->setText("拒绝");
    rejectBtn->setStyleSheet(R"(
        QPushButton {
           background-color: #F44336;
           border: none;
           border-radius: 8px;
           color: white;
           font-size: 12px;
           padding: 8px 15px;
        }
        QPushButton:hover {
            background-color: #D32F2F;
        }
        QPushButton:pressed {
            background-color: #B71C1C;
        }
    )");
    rejectBtn->setFixedWidth(80);

    // 3. 添加到布局管理器
    layout->addWidget(acceptBtn, 1, 1, 1, 2);
    layout->addWidget(rejectBtn, 1, 3, 1, 2);
    layout->setRowMinimumHeight(1, 24); // 设置最小高度, 放在拉高

    // 4. 连接信号槽
    connect(acceptBtn, &QPushButton::clicked, this, &ApplyItem::acceptFriendApply);
    connect(rejectBtn, &QPushButton::clicked, this, &ApplyItem::rejectFriendApply);
}

void ApplyItem::active(){
    LOG() << "ApplyItem active.";
}

void ApplyItem::acceptFriendApply(){
    DataCenter* dataCenter = DataCenter::getInstance();
    dataCenter->acceptFriendApplyAsync(this->userId);
}

void ApplyItem::rejectFriendApply(){
    DataCenter* dataCenter = DataCenter::getInstance();
    dataCenter->rejectFriendApplyAsync(this->userId);
}














